﻿using CoreEx.Common.Extensions;
using CoreEx.Database.Query.Expressions;
using NUnit.Framework;

namespace CoreEx.Database.Query.Tests
{
    
    public abstract class QueryTranslatorTestBase : BaseFixture
    {                
        protected abstract DbQueryTranslator QueryTranslator { get; }

        protected DbExpressionFactory ExpressionFactory { get; private set; }

        protected QueryTranslatorTestBase()
        {
            ExpressionFactory = new DbExpressionFactory();
        }


        [Test]
        public void ShouldTranslateAndExpression()
        {
            var expression = ExpressionFactory.And(ExpressionFactory.Constant(1), ExpressionFactory.Constant(2));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(AndExpressionSyntax,result.Sql);
        }

        [Test]
        public void ShouldTranslateAddExpression()
        {
            var expression = ExpressionFactory.Add(ExpressionFactory.Constant(1), ExpressionFactory.Constant(2));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(AddExpressionSyntax,result.Sql);
        }

        [Test]
        public void ShouldTranslateAliasExpression()
        {
            var expression = ExpressionFactory.Alias(ExpressionFactory.Table("SomeTable"), "t0");
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(AliasExpressionSyntax,result.Sql);
        }

        [Test]
        public void ShouldTranslateAssigntExpression()
        {
            var expression = ExpressionFactory.Assign(ExpressionFactory.Column("SomeColumn"),
                                                      ExpressionFactory.Constant(1));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(AssignExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateAvgExpression()
        {
            var expression = ExpressionFactory.Avg(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(AvgExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateColumnExpression()
        {
            var expression = ExpressionFactory.Column("SomeColumn");
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(ColumnExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateConcatExpression()
        {
            var expression = ExpressionFactory.Concat(ExpressionFactory.Table("SomeTable"),
                                                      ExpressionFactory.Table("SomeOtherTable"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(ConcatExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateConditionalExpression()
        {
            var expression = ExpressionFactory.Conditional(ExpressionFactory.Column("SomeColumn") == ExpressionFactory.Constant("SomeValue"),
                                ExpressionFactory.Constant("ValueWhenTrue"), ExpressionFactory.Constant("ValueWhenFalse"));

            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(ConditionalExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateConstantExpression()
        {
            var expression = ExpressionFactory.Constant(1);

            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(ConstantExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateCountExpression()
        {
            var expression = ExpressionFactory.Count(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(CountExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateDivideExpression()
        {
            var expression = ExpressionFactory.Divide(ExpressionFactory.Constant(1), ExpressionFactory.Constant(2));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(DivideExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateEqualExpression()
        {
            var expression = ExpressionFactory.Equal(ExpressionFactory.Column("SomeColumn"),
                                                     ExpressionFactory.Constant("SomeValue"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(EqualExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateExistsExpression()
        {
            var expression =
                ExpressionFactory.Exists(ExpressionFactory.Select(f => f.Column("SomeColumn")).From(f => f.Table("SomeTable")));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(ExistsExpressionSyntax.Strip(), result.Sql.Strip());
        }

        [Test]
        public void ShouldTranslateGreaterThanExpression()
        {
            var expression =
                ExpressionFactory.GreaterThan(ExpressionFactory.Column("SomeColumn"),
                                              ExpressionFactory.Constant("SomeValue"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(GreaterThanExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateGreaterThanOrEqualExpression()
        {
            var expression =
                ExpressionFactory.GreaterThanOrEqual(ExpressionFactory.Column("SomeColumn"),
                                              ExpressionFactory.Constant("SomeValue"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(GreaterThanOrEqualExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateInExpressionUsingValueRange()
        {
            var expression =
                ExpressionFactory.In(ExpressionFactory.Column("SomeColumn"), new object[] {1, 2});
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(InValueRangeExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateInExpressionUsingSubQuery()
        {
            var expression =
                ExpressionFactory.In(ExpressionFactory.Column("SomeColumn"),
                                     ExpressionFactory.Select(f => f.Column("SomeOtherColumn")).From(
                                         f => f.Table("SomeOtherTable")));

            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(InSubQueryExpressionSyntax.Strip(), result.Sql.Strip());
        }

        [Test]
        public void ShouldTranslateInnerJoinExpression()
        {
            var expression =
                ExpressionFactory.InnerJoin(ExpressionFactory.Table("SomeTable"),
                                            ExpressionFactory.Equal(ExpressionFactory.Column("SomeColumn"),
                                                                    ExpressionFactory.Column("SomeOtherColumn")));

            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(InnerJoinExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateLeftOuterJoinExpression()
        {
            var expression =
                ExpressionFactory.LeftOuterJoin(ExpressionFactory.Table("SomeTable"),
                                            ExpressionFactory.Equal(ExpressionFactory.Column("SomeColumn"),
                                                                    ExpressionFactory.Column("SomeOtherColumn")));

            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(LeftOuterJoinExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateRightOuterJoinExpression()
        {
            var expression =
                ExpressionFactory.RightOuterJoin(ExpressionFactory.Table("SomeTable"),
                                            ExpressionFactory.Equal(ExpressionFactory.Column("SomeColumn"),
                                                                    ExpressionFactory.Column("SomeOtherColumn")));

            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(RightOuterJoinExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateLengthExpression()
        {
            var expression =
                ExpressionFactory.Length(ExpressionFactory.Column("SomeColumn"));

            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(LengthExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateLessThanExpression()
        {
            var expression =
                ExpressionFactory.LessThan(ExpressionFactory.Column("SomeColumn"),
                                              ExpressionFactory.Constant("SomeValue"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(LessThanExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateLessThanOrEqualExpression()
        {
            var expression =
                ExpressionFactory.LessThanOrEqual(ExpressionFactory.Column("SomeColumn"),
                                              ExpressionFactory.Constant("SomeValue"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(LessThanOrEqualExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateListExpression()
        {
            var expression =
                ExpressionFactory.List(new []{ExpressionFactory.Column("SomeColumn"),
                                       ExpressionFactory.Column("SomeOtherColumn")});
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(ListExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateMaxExpression()
        {
            var expression =
                ExpressionFactory.Max(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(MaxExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateMinExpression()
        {
            var expression =
                ExpressionFactory.Min(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(MinExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateMultiplyExpression()
        {
            var expression = ExpressionFactory.Multiply(ExpressionFactory.Constant(1), ExpressionFactory.Constant(2));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(MultiplyExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateSubstractExpression()
        {
            var expression = ExpressionFactory.Subtract(ExpressionFactory.Constant(1), ExpressionFactory.Constant(2));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(SubstractExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateNotExpression()
        {
            var expression =
                ExpressionFactory.Not(ExpressionFactory.Equal(ExpressionFactory.Column("SomeColumn"),
                                                              ExpressionFactory.Constant(1)));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(NotExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateNotEqualExpression()
        {
            var expression = ExpressionFactory.NotEqual(ExpressionFactory.Column("SomeColumn"),
                                                 ExpressionFactory.Constant("SomeValue"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(NotEqualExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateOrExpression()
        {
            var expression = ExpressionFactory.Or(ExpressionFactory.Constant(1), ExpressionFactory.Constant(2));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(OrExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateOrderByAscendingExpression()
        {
            var expression = ExpressionFactory.OrderByAscending(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(OrderByAscendingExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateOrderByDescendingExpression()
        {
            var expression = ExpressionFactory.OrderByDescending(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(OrderByDescendingExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslatePrefixExpression()
        {
            var expression = ExpressionFactory.Prefix(ExpressionFactory.Column("SomeColumn"), "t0");
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(PrefixExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateReplaceExpression()
        {
            var expression = ExpressionFactory.Replace(ExpressionFactory.Column("SomeColumn"),
                                                       ExpressionFactory.Constant("OldValue"),
                                                       ExpressionFactory.Constant("NewValue"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(ReplaceExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateReverseExpression()
        {
            var expression = ExpressionFactory.Reverse(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(ReverseExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateSoundExExpression()
        {
            var expression = ExpressionFactory.SoundEx(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(SoundExExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateSumExpression()
        {
            var expression = ExpressionFactory.Sum(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(SumExpressionSyntax , result.Sql);
        }

        [Test]
        public void ShouldTranslateTableExpression()
        {
            var expression = ExpressionFactory.Table("SomeTable");
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(TableExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateToLowerExpression()
        {
            var expression = ExpressionFactory.ToLower(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(ToLowerExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateToUpperExpression()
        {
            var expression = ExpressionFactory.ToUpper(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(ToUpperExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateTrimExpression()
        {
            var expression = ExpressionFactory.Trim(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(TrimExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateTrimStartExpression()
        {
            var expression = ExpressionFactory.TrimStart(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(TrimStartExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateTrimEndExpression()
        {
            var expression = ExpressionFactory.TrimEnd(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(TrimEndExpressionSyntax, result.Sql);
        }
        
        [Test]
        public void ShouldTranslateSubStringExpression()
        {
            var expression = ExpressionFactory.SubString(ExpressionFactory.Column("SomeColumn"),
                                                         ExpressionFactory.Constant(1), ExpressionFactory.Constant(2));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(SubStringExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateDateExpression()
        {
            var expression = ExpressionFactory.Date(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(DateExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateYearExpression()
        {
            var expression = ExpressionFactory.Year(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(YearExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateMonthExpression()
        {
            var expression = ExpressionFactory.Month(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(MonthExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateHourExpression()
        {
            var expression = ExpressionFactory.Hour(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(HourExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateNowExpression()
        {
            var expression = ExpressionFactory.Now();
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(NowExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateTodayExpression()
        {
            var expression = ExpressionFactory.ToDay();
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(ToDayExpressionSyntax, result.Sql);
        }


        [Test]
        public void ShouldTranslateMinuteExpression()
        {
            var expression = ExpressionFactory.Minute(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(MinuteExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateSecondExpression()
        {
            var expression = ExpressionFactory.Second(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(SecondExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateMillisecondExpression()
        {
            var expression = ExpressionFactory.Millisecond(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(MillisecondExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateDayOfYearExpression()
        {
            var expression = ExpressionFactory.DayOfYear(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(DayOfYearExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateDayOfMonthExpression()
        {
            var expression = ExpressionFactory.DayOfMonth(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(DayOfMonthExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateDayOfWeekExpression()
        {
            var expression = ExpressionFactory.DayOfWeek(ExpressionFactory.Column("SomeColumn"));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(DayOfWeekExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateAddYearsExpression()
        {
            var expression = ExpressionFactory.AddYears(ExpressionFactory.Column("SomeColumn"),ExpressionFactory.Constant(1));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(AddYearsExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateAddMonthsExpression()
        {
            var expression = ExpressionFactory.AddMonths(ExpressionFactory.Column("SomeColumn"), ExpressionFactory.Constant(1));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(AddMonthsExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateAddDaysExpression()
        {
            var expression = ExpressionFactory.AddDays(ExpressionFactory.Column("SomeColumn"), ExpressionFactory.Constant(1));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(AddDaysExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateAddHoursExpression()
        {
            var expression = ExpressionFactory.AddHours(ExpressionFactory.Column("SomeColumn"), ExpressionFactory.Constant(1));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(AddHoursExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateAddMinutesExpression()
        {
            var expression = ExpressionFactory.AddMinutes(ExpressionFactory.Column("SomeColumn"), ExpressionFactory.Constant(1));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(AddMinutesExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateAddSecondsExpression()
        {
            var expression = ExpressionFactory.AddSeconds(ExpressionFactory.Column("SomeColumn"), ExpressionFactory.Constant(1));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(AddSecondsExpressionSyntax, result.Sql);
        }

        [Test]
        public void ShouldTranslateAddMillisecondsExpression()
        {
            var expression = ExpressionFactory.AddMilliseconds(ExpressionFactory.Column("SomeColumn"), ExpressionFactory.Constant(1));
            var result = QueryTranslator.Translate(expression);
            Assert.AreEqual(AddMilliSecondsExpressionSyntax, result.Sql);
        }

        public abstract string AndExpressionSyntax { get; }

        public abstract string AddExpressionSyntax { get; }

        public abstract string AliasExpressionSyntax { get; }
        
        public abstract string AssignExpressionSyntax { get; }

        public abstract string AvgExpressionSyntax { get; }

        public abstract string ColumnExpressionSyntax { get; }

        public abstract string ConcatExpressionSyntax { get; }

        public abstract string ConditionalExpressionSyntax { get; }

        public abstract string ConstantExpressionSyntax { get; }

        public abstract string CountExpressionSyntax { get; }

        public abstract string DivideExpressionSyntax { get; }

        public abstract string EqualExpressionSyntax { get; }
        
        public abstract string ExistsExpressionSyntax { get; }

        public abstract string GreaterThanExpressionSyntax { get; }

        public abstract string GreaterThanOrEqualExpressionSyntax { get; }

        public abstract string InValueRangeExpressionSyntax { get; }

        public abstract string InSubQueryExpressionSyntax { get; }

        public abstract string InnerJoinExpressionSyntax { get; }

        public abstract string LeftOuterJoinExpressionSyntax { get; }

        public abstract string RightOuterJoinExpressionSyntax { get; }

        public abstract string LengthExpressionSyntax { get; }

        public abstract string LessThanExpressionSyntax { get; }

        public abstract string LessThanOrEqualExpressionSyntax { get; }

        public abstract string ListExpressionSyntax { get; }
        
        public abstract string MaxExpressionSyntax { get; }

        public abstract string MinExpressionSyntax { get; }

        public abstract string MultiplyExpressionSyntax { get; }

        public abstract string SubstractExpressionSyntax { get; }

        public abstract string NotExpressionSyntax { get; }

        public abstract string NotEqualExpressionSyntax { get; }

        public abstract string OrExpressionSyntax { get; }
        
        public abstract string OrderByAscendingExpressionSyntax { get; }

        public abstract string OrderByDescendingExpressionSyntax { get; }

        public abstract string PrefixExpressionSyntax { get; }

        public abstract string ReplaceExpressionSyntax { get; }

        public abstract string ReverseExpressionSyntax { get; }

        public abstract string SoundExExpressionSyntax { get; }

        public abstract string SumExpressionSyntax { get; }

        public abstract string TableExpressionSyntax { get; }

        public abstract string ToLowerExpressionSyntax { get; }

        public abstract string ToUpperExpressionSyntax { get; }

        public abstract string TrimExpressionSyntax { get; }

        public abstract string TrimStartExpressionSyntax { get; }

        public abstract string TrimEndExpressionSyntax { get; }

        public abstract string SubStringExpressionSyntax { get; }

        public abstract string DateExpressionSyntax { get; }

        public abstract string YearExpressionSyntax { get; }

        public abstract string MonthExpressionSyntax { get; }

        public abstract string HourExpressionSyntax { get; }

        public abstract string MinuteExpressionSyntax { get; }

        public abstract string SecondExpressionSyntax { get; }

        public abstract string MillisecondExpressionSyntax { get; }

        public abstract string DayOfYearExpressionSyntax { get; }

        public abstract string DayOfMonthExpressionSyntax { get; }

        public abstract string DayOfWeekExpressionSyntax { get; }

        public abstract string AddYearsExpressionSyntax { get; }

        public abstract string AddMonthsExpressionSyntax { get; }

        public abstract string AddDaysExpressionSyntax { get; }

        public abstract string AddHoursExpressionSyntax { get; }
        
        public abstract string AddMinutesExpressionSyntax { get; }

        public abstract string AddSecondsExpressionSyntax { get; }
        
        public abstract string AddMilliSecondsExpressionSyntax { get; }

        public abstract string NowExpressionSyntax { get; }

        public abstract string ToDayExpressionSyntax { get; }
    }
}
